package com.lyf.juc.practice.lock;

import org.junit.Test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author LYF
 * @date 2022/7/6
 */
public class LockSupportTest2 {
    /*
    wait\notify
    考虑两种情况：
    1.不加 synchronized
    Monitor异常
    2.先Notify后wait
    线程卡死
     */
    @Test
    public void test0() throws InterruptedException {
        Object lock = new Object();
        new Thread(()->{
            synchronized (lock){
                System.out.println("线程1 进入");
//                try {
//                    lock.wait();//等待通知
                //“sleep方法没有释放锁，而wait方法释放了锁，使得其他线程可以使用同步控制块或者方法。”
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程1 出去");
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            synchronized (lock){
                System.out.println("线程2 进入");

                  //  lock.notify();//等待通知

                System.out.println("线程2 出去");
            }
        }).start();

        TimeUnit.SECONDS.sleep(40);
    }

    /*
    Condition的await,signal -- 结合代码块思考 lock.lock()类似 synchronized
     */
    @Test
    public void test1(){
       // ReentrantLock lock = ReentrantLock
        Lock lock = new ReentrantLock();
        // sync.newCondition -- sync  extends aqs
        Condition condition = lock.newCondition();

        new Thread(()->{
            lock.lock();
            try {
                System.out.println("Thread-1 exec...");
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread-1 out...");
            }finally {
                lock.unlock();
            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            lock.lock();
            try {
                System.out.println("Thread-2 exec...");
                    condition.signal();
                System.out.println("Thread-2 out...");
            }finally {
                lock.unlock();
            }
        }).start();

    }

    /*
    park,unpark
    park阻塞， unPark 唤醒
     */
    @Test
    public void test2() throws InterruptedException {

        Thread t1 = new Thread(()->{
            System.out.println("thread1 come in...");
            LockSupport.park("测试1");
            System.out.println("out1...");
        });//.start();
        Thread t2 = new Thread(()->{
            System.out.println("thread2 come in...");
            LockSupport.park("测试2");
            System.out.println("out2...");
        });//.start();
        t1.start();
        t2.start();

        TimeUnit.SECONDS.sleep(2);
        System.out.println(LockSupport.getBlocker(t1)+"::"
        +LockSupport.getBlocker(t2));
        LockSupport.unpark(t1);// 唤醒，发许可证,区分semaphore
        //LockSupport.unpark(t1);
        LockSupport.unpark(t2);
    }
}
